<template>
	<div class="mc-calculate">
		<template v-if="!detailed">
			<Input
				v-if="isStorage == 1"
				v-model="innerValue"
				readonly
				placeholder="用于展示计算结果，且数据不会保存"
			/>
			<Input
				v-else
				v-model="innerValue"
				readonly
				placeholder="用于展示计算结果，且数据同时会保存入库"
			/>
		</template>
		<p v-else>{{innerValue}}</p>
		<p
			v-if="isAmountChinese"
			class="isAmountChinese amountChinese"
		>
			{{amountChineseName}}
		</p>
	</div>
</template>
<script>
import {
	toRPN,
	mergeNumberOfExps,
	calcRPN,
	thousandsFormat,
	debounce,
} from '../../utils';
import convertToChineseNumber from 'number2chinesenumber';
import {Input} from 'element-ui';
export default {
	name:'McCalculate',
	components:{
		Input
	},
	model:{
		prop:'value',
		event:'input',
	},
	props:[
		'value',
		'formData',
		'expression',
		'tableVModel',
		'componentVModel',
		'isStorage',
		'rowIndex', // 计算公式放在表格中时， 需要获取在表格中的行位置
		'detailed',
		'isAmountChinese',
		'thousands',
		'precision',
	],
	data(){
		return {
			innerValue:this.value,
			RPN_EXP:toRPN(mergeNumberOfExps(this.expression)),
			setValue:0,
			amountChineseName:'',
		};
	},
	computed:{
		rootFormData(){
			return this.formData || this.getFormData();
		},
	},
	watch:{
		formData:{
			handler:function(val){
				if(!val) return;
				if(!this.computeExps){
                    // formData更新可能比较频繁
					this.computeExps = debounce(this.execRPN, 100);
				}
				this.computeExps();
			},
			deep:true,
			immediate:true,
		},
	},
	methods:{
		getFormData(){
			let root = this.$parent;
			while(root){
				if('vmFormData' in root){
					return root.vmFormData;
				}
				root = root.$parent;
			}
		},
        /**
         * 获取指定组件的值
         */
		getFormVal(model){
			try{
				if(model.indexOf('.') > -1){
					const [tableVModel, cmpVModel] = model.split('.');
					if(typeof this.rowIndex === 'number'){
						return this.rootFormData[tableVModel][this.rowIndex][cmpVModel] || 0;
					}else{
						return this.rootFormData[tableVModel].reduce(
							(sum, c) => (c[cmpVModel] ? Number(c[cmpVModel]) : 0) + sum,
							0,
						);
					}
				}
				return this.rootFormData[model] || 0;
			}catch(error){
				console.warn('计算公式出错, 可能包含无效的组件值', error);
				return 0;
			}
		},
        /**
         * 计算表达式
         */
		execRPN(){
			const temp = this.RPN_EXP.map((t) =>
				typeof t === 'object' ? this.getFormVal(t.__vModel__) : t,
			);
			this.innerValue = Number.parseFloat(calcRPN(temp));
			this.setValue = JSON.parse(JSON.stringify(this.innerValue));
			if(isNaN(this.innerValue))this.innerValue = 0;
			this.innerValue = this.innerValue.toFixed(this.precision || 0);
			this.$emit('input', this.setValue);
			if(this.rowIndex >= 0 && this.componentVModel && this.tableVModel){
				if(
					this.rootFormData[this.tableVModel][this.rowIndex][this.componentVModel]
					!== this.innerValue
				){
					this.$emit('change', this.setValue);
				}
			}
			if(this.thousands){
				this.innerValue = thousandsFormat(this.innerValue);
			}
			if(this.isAmountChinese){
				this.amountChineseName = convertToChineseNumber(!isNaN(this.setValue) ? this.setValue : 0, 'maxAmount');
			}
		},
	},
};
</script>
<style lang="scss" scoped>
.mc-calculate {
    .isAmountChinese {
        color: #c0c0c0;
    }
    .amountChinese {
        margin-left: 15px;
    }
}
</style>